#ifndef __NET_TOOLKITS__
#include "CommonMacro.h"
#include <WinSock2.h>
#include <iostream>
#include <string>
#include <process.h>
#include <queue>
using namespace std;

//wsastartup
class DLL_CLASS WinSockDamon
{
private:
	WSADATA _winSockData;
public:
	WinSockDamon();
	~WinSockDamon();
};



//iocpclient
const int OP_READ = 1;
const int OP_WRITE = 2;
const int OP_ACCEPT = 3;

class DLL_CLASS IocpClient{
public:
	OVERLAPPED overLapped_recv;
	OVERLAPPED overLapped_send;
	SOCKET connectSocket;
	int operationCode;
	WSABUF   wsRecvBuff;
	WSABUF   wsSendBuff;
	udword    dwRecvBytes;
	udword	  dwSentBytes;
	udword    dwFlags;
public:
	YHBOOL connect(string ipaddr, int port);
	int sendAsync(const byte* frame, int framebegin, int len);
	int send(const byte* frame, int framebegin, int len);
public:
	IocpClient(int recvBufferSize=4096);
	~IocpClient();
};

//iocp delegate class
class DLL_CLASS IocpServerDelegate
{
public:
	virtual void onRead(IocpClient * client, byte *buffer, int len){}
	virtual void onAccept(IocpClient * client){}
	virtual void onClose(IocpClient * client){}
};

class DLL_CLASS IocpClientPool{
protected:
	queue<IocpClient*> *_iocpClientQueue;
	int _maxPoolSize;
	HANDLE _poolMutex;
private:
	void _extendpool();
public:
	IocpClientPool(int maxPoolSize = 500);
	~IocpClientPool();
public:
	IocpClient* popUp();
	void pushBack(IocpClient* IocpClient);
	void destroyPool();
};

//iocpserver
class DLL_CLASS IocpServer{
public:
	IocpServer();
	~IocpServer();
private:
	SOCKET _acceptSocket;
	YHBOOL _serverAccepting;
	YHBOOL _serverReading;
	HANDLE _hIocp;
	SOCKET _serverSocket;
	IocpClientPool *_clientPool;
	IocpServerDelegate *_processor;
protected:
	HANDLE _hIocpWorkThreadHandle;
	uint32 _iIocpWorkTHreadId;
	HANDLE _hIocpAcceptThreadHandle;
	uint32 _iIocpAcceptTHreadId;
private:
	YHBOOL bindToAddress(string &ipAddr, int port);
public:
	YHBOOL startListen(string &ipAddr, int port, int queuelen);
	virtual void onRead(IocpClient * client, byte *buffer, int len);
	virtual void onAccept(SOCKET socket);
	virtual void onClose(IocpClient * client);
	YHBOOL setIoCompleteionPort(SOCKET socket, void *p, char *buf = NULL, int len = 0);
public:
	YHBOOL isServerAccepting();
	YHBOOL isServerReading();
	HANDLE getIocpHandle();
	SOCKET getServerSocket();
	void setProcessor(IocpServerDelegate* p);
public:
	static uint32 __stdcall iocpWorkThreadProc(LPVOID param);
	static uint32 __stdcall iocpAcceptThreadProc(LPVOID param);

};
#define __NET_TOOLKITS__
#endif